Skip to content

Add configurable :group_by option for the underlying Registry#210

Merged
josevalim merged 1 commit intophoenixframework:mainfrom
studzien:registry-keys-option
Apr 30, 2026
Merged

Add configurable :group_by option for the underlying Registry#210
josevalim merged 1 commit intophoenixframework:mainfrom
studzien:registry-keys-option

Conversation

@studzien
Copy link
Copy Markdown
Contributor

@studzien studzien commented Apr 28, 2026

Summary

Adds a :group_by option to Phoenix.PubSub, forwarded to the underlying Registry. Defaults to :pid (no behavior change). Accepts :key or pid.

{Phoenix.PubSub, name: :my_pubsub, group_by: :pid}

Motivation

{:duplicate, :key}, added in Registry elixir-lang/elixir#14654 (which cites #198 as motivation), shards by topic key — better for workloads with many topics and few subscribers per topic, since key-based lookups touch a single partition. The default group_by: :pid (≡ keys: {:duplicate, :pid}) is still best when topics have many subscribers each.

See Registry.start_link/1 for trade-offs.

Notes

  • Using group_by: :key requires Elixir 1.19+

Comment thread lib/phoenix/pubsub.ex Outdated
one of `:unique`, `:duplicate`, `{:duplicate, :pid}`, or
`{:duplicate, :key}` (defaults to `:duplicate`, which is equivalent
to `{:duplicate, :pid}`). With `:unique`, subscribing the same
process to the same topic twice returns
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought unique would only allow a single process per topic, no? It probably doesn't make sense? Perhaps the option should be group_by: :pid | :key?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's right. It doesn't make much sense, but I can think of scenarios where it does (like limiting to one subscriber per user topic).
The main reason I went with just passing the option directly to Registry was that we can't use the {:duplicate, _} form in Elixir < 1.19 (it crashes in CI runs).
Would making an Elixir-dependent test be the way to go here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default to :duplicate and use the tuple only of group_by is given. Let’s not support unique :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed. Also added a test dependent on the Elixir version, but maybe we don't need that

Selects how the underlying Registry partitions subscriptions. Defaults
to :pid (current behavior). Accepts :pid or :key.

  - :pid (default) groups entries by subscriber pid; best when topics
    have many subscribers each. Translates to keys: :duplicate.
  - :key groups entries by topic so key-based lookups touch a single
    partition; best when there are many topics with few subscribers
    each. Translates to keys: {:duplicate, :key}, which requires
    Elixir 1.19+ (see elixir-lang/elixir#14654).

Invalid values raise ArgumentError at supervisor start.

Refs: phoenixframework#198
@studzien studzien force-pushed the registry-keys-option branch from 81a7706 to 971441a Compare April 30, 2026 11:20
@josevalim josevalim merged commit c1ae9f7 into phoenixframework:main Apr 30, 2026
5 checks passed
@josevalim
Copy link
Copy Markdown
Member

💚 💙 💜 💛 ❤️

@studzien studzien changed the title Add configurable :keys option for the underlying Registry Add configurable :group_by option for the underlying Registry Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants